﻿using System;
using System.Collections.Generic;

namespace FastEmit
{
    public class TypeAccessor
    {
        private readonly Type _type;

        private readonly Dictionary<string, MemberGetter> dictGetter = [];

        private readonly Dictionary<string, MemberSetter> dictSetter = [];

        public TypeAccessor(Type type)
        {
            _type = type;

            foreach (var item in type.GetProperties())
            {
                MemberDict.Add(item.Name, item.PropertyType);

                try
                {
                    var getter = PropertyExtensions.DelegateForGetPropertyValue(type, item.Name);
                    dictGetter.Add(item.Name, getter);
                }
                catch { }

                try
                {
                    var setter = PropertyExtensions.DelegateForSetPropertyValue(type, item.Name);
                    dictSetter.Add(item.Name, setter);
                }
                catch { }

            }

            foreach (var item in type.GetFields())
            {
                MemberDict.Add(item.Name, item.FieldType);

                try
                {
                    var getter = FieldExtensions.DelegateForGetFieldValue(type, item.Name);
                    dictGetter.Add(item.Name, getter);
                }
                catch { }

                try
                {
                    var setter = FieldExtensions.DelegateForSetFieldValue(type, item.Name);
                    dictSetter.Add(item.Name, setter);
                }
                catch { }
            }
        }

        public Dictionary<string, Type> MemberDict { get; } = [];

        public object GetValue(object obj, string name)
        {
            return dictGetter[name](obj);
        }

        public void SetValue(object obj, string name, object value)
        {
            dictSetter[name](obj, value);
        }

        public void SetValueConvert(object obj, string name, string value)
        {
            dictSetter[name](obj, TypeConverter.Get(MemberDict[name], value));
        }

        public void SetValueConvert(object obj, string name, object value)
        {
            dictSetter[name](obj, TypeConverter.Get(MemberDict[name], value));
        }

        /// <summary>
        /// 静态
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public object GetStaticValue(string name)
        {
            return dictGetter[name](_type);
        }

        /// <summary>
        /// 静态
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public void SetStaticValue(string name, object value)
        {
            dictSetter[name](_type, value);
        }

        public void SetStaticValueConvert(string name, string value)
        {
            dictSetter[name](_type, TypeConverter.Get(MemberDict[name], value));
        }

        public void SetStaticValueConvert(string name, object value)
        {
            dictSetter[name](_type, TypeConverter.Get(MemberDict[name], value));
        }
    }

}
